using System;
using System.Collections;
using System.Globalization;
using System.Security.Principal;
using System.Threading;
using System.Web;
using Sedna.Core;
using Sedna.Core.Security;
using Sedna.Domain;

namespace Sedna.UI.Access.Actions
{

	/// <summary>
	/// A special authenticator that is used primarily for testing purposes.
	/// This authenticator is not aware of the underlying authentication scheme, thus it does not
	/// install any propriatory user info information properly and is not suitable for 
	/// complete vertical testing.
	/// However, this authenticator can be used to test the WebUI in an isolated mode or
	/// to unit-test the collaborators that uses an instance of IAuthenticator and do not 
	/// rely (which is always a good practice) on the underlying logic such as 
	/// injecting properiatory user info in a context.
	/// 
	/// Since all the collaborators of the Authenticator use it to check whether 
	/// a IPrincipal has necessary permission, it is vital to feed the Authenticator with
	/// the list of those roles that are necessary for a User's normal work.
	/// However, it is not possible to differenciate Users by their roles using this Authenticator, 
	/// as all the Users will get the same role list. If it is necessary to check the System against
	/// different role list, proper version of an Authenticator should be used 
	/// (such as <see cref="WindowsPrincipalAuthenticator"/>).
	/// 
	/// The list of roles must contain proper role names that are relevant to the WebUI, 
	/// i.e. that must be 'internal' WebUI roles instead of external (e.g. host or NT domain based) permissions.
	/// </summary>
	public class FakeAuthenticator : AbstractAuthenticator
	{

		private ArrayList principalRoles = new ArrayList();

		public FakeAuthenticator()
		{
		}

		public IList PrincipalRoles
		{
			set { principalRoles = (ArrayList)value; }
		}

		public override IPrincipal Authenticate(string userName, string credentials)
		{
			if("sa" != userName || userName != credentials)
			{
				throw new LoginException("Fake Authenticator supports sa/sa only.");
			}
			GenericIdentity identity = new GenericIdentity(userName);
			string[] roles = (string[])principalRoles.ToArray(typeof(string));
            SednaWorkPrincipal principal = new SednaWorkPrincipal(identity, roles, new User());

			Thread.CurrentPrincipal = principal;
			return principal;
			
		}

		public override void SignOut(IPrincipal principal)
		{
		}

        // Below are the fake implementations of InjectPrincipal

	    public override bool InjectPrincipal()
	    {
	        //throw new NotImplementedException();
            return true;
	    }

		//bool IAuthenticator.InjectPrincipal(HttpContext context)
		//{
		//    //throw new NotImplementedException();
		//    return true;
		//}

	    public override bool InjectPrincipal(IPrincipal principal)
	    {
	        //throw new NotImplementedException();
            return true;
	    }

	    public override bool InjectPrincipal(IPrincipal principal, HttpContext context)
	    {
	        //throw new NotImplementedException();
            return true;
	    }

	    public override bool InjectPrincipal(HttpContext context)
        {
            SednaWorkPrincipal principal = UserMapper.RestoreCurrentState();
            if (principal == null) return false;
            Thread.CurrentPrincipal = principal;
            Thread.CurrentThread.CurrentCulture = principal.Culture;
            Thread.CurrentThread.CurrentUICulture = principal.Culture;
            HttpContext.Current.User = principal;
			return true;
	    }
	}
}
